home *** CD-ROM | disk | FTP | other *** search
- /* dates.c The dates functions to be used with C. The dates are
- input and output as strings with / delimiters. A blank date
- (ie not yet filled in) will be " / / ". The default is
- similiar to Dbase format only using the year portion of the date
- but if the CENTURY flag is true then the century will be used.
- Released to the Public Domain for any purpose on 11 Mar 1989
- Gerry Rohr.
- */
-
- #include "dates.h"
- #include <string.h>
- #include <stdlib.h>
-
- /* prototype for function which is local only */
- static int leapyear(int yr); /* Returns true if leap year */
-
- /* the following is a global array used by more than one of the functions */
- int MONTHTOTAL[] = {0,0,31,59,90,120,151,181,212,243,273,304,334,365};
-
- char *dtoa(DATE in_date)
- { /*Returns a character pointer to the date string representation
- of the DATE type data set (long)
- */
- static char dt[11]; /* where the date is */
- char *dp; /* pointer returned */
- char dt_st[11]; /* temp storage */
- int i;
-
- strcpy(dt,DATE_TEMP);
- dp = dt;
- if(in_date == 0L)
- return(dp);
- else
- {
- ltoa(in_date,dt_st,10); /* convert to a string */
- for(i=0;i<2;i++,dp++) dp[0] = dt_st[4+i]; /* month */
- dp++; /* skip the slash */
- for(i=0;i<2;i++,dp++) dp[0] = dt_st[6+i]; /* day */
- dp++;
- for(i=0;i<4;i++,dp++) dp[0] = dt_st[i]; /* year */
- dp = dt; /* reset pointer to beginning of string */
- return(dp);
- }
- } /* end of dtoa */
-
- int day(DATE in_date)
- { /* returns the day portion of a DATE */
- int lo_date;
-
- if(in_date == NO_DATE) return(0);
- lo_date = (in_date % 10000);
- return(lo_date % 100);
- } /* end of day */
-
- int month(DATE in_date)
- { /* returns the month portion of a DATE */
- int lo_date;
-
- if(in_date == NO_DATE) return(0);
- lo_date = (in_date % 10000);
- return(lo_date / 100);
- } /* end of month */
-
- int year(DATE in_date,int cf)
- { /* returns the year portion of a DATE. If cf is true returns
- 4 digit year else returns two digits
- */
- int hi_date;
-
- if(in_date == NO_DATE) return(0);
- hi_date = (in_date / 10000);
- if(cf)
- return(hi_date);
- else
- return(hi_date % 100);
- } /* end of year */
-
- void greg_to_jul(DATE in_date,JULDATE *jdt)
- { /* converts the gregorian date to the julian date, operates on the
- JULDATE structure defined by user.
- */
- int yr = year(in_date,1);
- int mo = month(in_date);
- int dy = day(in_date);
-
- jdt->yr = yr;
- if(yr == 0 && mo == 0 && dy == 0) jdt->day = 0;
- else
- {
- /* calculate leap year here */
- if((leapyear(yr)) && (mo > 2)) jdt->day = 1;
- else jdt->day = 0;
- jdt->day = MONTHTOTAL[mo] + dy;
- }
- } /* end of greg_to_jul */
-
- DATE jul_to_greg(JULDATE *jdt)
- { /* Converts user defined (pointer to user variable) julian date
- to gregorian date, returns the gregorian date.
- */
- int i,workday = jdt->day;
- int yr= jdt->yr;
- int mo = 0,dy = 0;
- DATE dt;
-
- if((jdt->yr > 0) || (jdt->day > 0))
- {
- if((leapyear(jdt->yr)) && (workday > 59))
- workday -= 1;
- i = 1;
- while(workday > MONTHTOTAL[i]) i++;
- mo = i - 1;
- dy = workday - MONTHTOTAL[mo];
- if((leapyear(jdt->yr)) && (jdt->day == 60))
- dy += 1;
- }
- /* now to put the yr, mo, and dy into the DATE format */
- dt = (long)yr;
- dt = (dt * 100) + (long)mo;
- dt = (dt * 100) + (long)dy;
- return(dt);
- } /* end of jul_to_greg */
-
- static int leapyear(int yr)
- { /* Returns true (1) if year (all 4 digits) is a leap year, else
- returns false (0).
- */
- if((((yr % 4) == 0) && (!((yr % 100) == 0))) || ((yr % 400) == 0))
- return(1);
- else
- return(0);
- } /* end of leapyear */
-
- void next_day(DATE *dt)
- { /* Adds one day to the callers DATE variable. Be sure to pass
- the address to this function. The callers data item is changed.
- */
- JULDATE jdt;
-
- greg_to_jul(*dt,&jdt);
- jdt.day += 1;
- if((leapyear(jdt.yr) && jdt.day == 367) ||
- (!(leapyear(jdt.yr)) && (jdt.day == 366)))
- {
- jdt.yr += 1;
- jdt.day = 1;
- }
- *dt = jul_to_greg(&jdt);
- } /* end of next_day */
-
- void prev_day(DATE *dt)
- { /* Subtracts one day to the callers DATE variable. Be sure to pass
- the address to this function. The callers data item is changed.
- */
- JULDATE jdt;
-
- greg_to_jul(*dt,&jdt);
- jdt.day -= 1;
- if(jdt.day < 1)
- {
- jdt.yr -= 1;
- if(leapyear(jdt.yr))
- jdt.day = 366;
- else
- jdt.day = 365;
- }
- *dt = jul_to_greg(&jdt);
- } /* end of prev_day */
-
- int valid_date(DATE dt)
- { /* checks if date is valid. Return code indicates where the non valid
- data was found.
- 0 = Valid date
- 1 = Month invalid
- 2 = Day invalid
- 4 = Year is invalid
- */
- int yr = year(dt,TRUE);
- int mo = month(dt);
- int dy = day(dt);
- int rc = 0;
-
- if(dt != NO_DATE) /* only check if some date is present */
- {
- switch(mo)
- {
- case 1 :
- case 3 :
- case 4 :
- case 6 :
- case 9 :
- case 11:if(dy < 1 || dy > 31) rc += 2;
- break;
- case 5 :
- case 7 :
- case 8 :
- case 10:
- case 12:if(dy < 1 || dy > 30) rc += 2;
- break;
- case 2 :if((leapyear(yr) && (dy > 29)) ||
- (!(leapyear(yr)) && (dy > 28))) rc += 2;
- break;
- default:rc += 1;
- }
- if(yr == 0) rc += 4;
- }
- return(rc);
- } /* end of valid_date */
-
- char *month_name(int mon)
- { /* returns char pointer to month name given the number of the month
- desired. The string pointed to is read only.
- */
- static char *month[] = {"UNKNOWN","January","February","March",
- "April","May","June",
- "July","August","September",
- "October","November","December"};
-
- if(mon < 1 || mon > 12) return(month[0]);
- else
- return(month[mon]);
- } /* end of month_name */
-
- char *day_name(DATE in_date)
- { /* Returns character pointer to string name of the day of the week,
- Note that this is a read only string.
- */
- static char *dayname[] = {"Sunday","Monday","Tuesday",
- "Wednesday","Thursday","Friday",
- "Saturday","UNKNOWN"};
- int dow = zeller(in_date);
-
- if(dow < 0 || dow > 6) return(dayname[7]);
- else return(dayname[dow]);
- } /* end of day_name */
-
- int zeller(DATE dt)
- { /* Gets day of week from date using Zeller's Congruence. */
- int yr = year(dt,TRUE);
- int mo = month(dt);
- int dy = day(dt);
- int century;
-
- if(mo > 2) mo -= 2;
- else
- {
- mo = mo += 10;
- yr -= 1;
- }
- century = yr / 100;
- yr = (yr % 100);
- return((dy - 1 + ((13 * mo - 1) / 5) + (5 * yr / 4) +
- century / 4 - 2 * century + 1) % 7);
- } /* end of zeller */
-
- char *jul_dt_st(JULDATE *jdt)
- { /* returns char pointer to Julian date string. This date string is
- a read only string.
- */
- char day_st[4];
- static char jdt_st[9];
- char *s;
- int i;
-
- s = jdt_st;
- for(i=0;i<9;i++) jdt_st[i] = '\0';
- if((jdt->yr == 0) && (jdt->day == 0)) strcpy(jdt_st,"YYYY/DDD");
- else
- {
- itoa(jdt->yr,jdt_st,10);
- strcat(jdt_st,"/");
- itoa(jdt->day,day_st,10);
- strcat(jdt_st,day_st);
- }
- return(s);
- } /* end of jul_dt_st */
-
- char *full_date_st(DATE dt)
- { /* Returns pointer to full date string. This is a read only string. */
- static char *dayname[] = {"Sunday","Monday","Tuesday",
- "Wednesday","Thursday","Friday",
- "Saturday","UNKNOWN"};
- static char *monname[] = {"UNKNOWN","January","February","March",
- "April","May","June","July","August",
- "September","October",",November","December"};
- static char fulldatest[30],ts[10];
- char *s;
- int yr = year(dt,TRUE);
- int mo = month(dt);
- int dy = day(dt);
-
- s = fulldatest;
- if(mo == 0 && dy == 0 && yr == 0) strcpy(fulldatest,"No Date");
- else
- {
- strcpy(fulldatest,dayname[zeller(dt)]);
- strcat(fulldatest,", ");
- strcat(fulldatest,monname[mo]);
- strcat(fulldatest," ");
- itoa(dy,ts,10);
- strcat(fulldatest,ts);
- strcat(fulldatest,", ");
- itoa(yr,ts,10);
- strcat(fulldatest,ts);
- }
- return(s);
- } /* end of full_date_st */
-
- /* end of dates.c */
-